package cn.edu.fudan.classifier;

import cn.edu.fudan.data.*;
import cn.edu.fudan.tools.BinarySearch;
import cn.edu.fudan.tools.GetConfig;
import cn.edu.fudan.tools.PAMAPClassifier;
import cn.edu.fudan.type.*;
import org.apache.log4j.Logger;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class PAMAPData {
	private static Logger logger = Logger.getLogger(PAMAPData.class);

	private static final String subject = "subject101";
	private static Activities lable = Activities.walking;
	private static PAMAPDimension dimension = PAMAPDimension.z_ankle;

	public static void main(String[] args) throws IOException {

		Config config = new GetConfig().getConfig();
		String path = config.getPath();

		String filePath = path + subject + "_extract";

		ReadData readData = new ReadData();
		ExtractFeature extractFeature = new ExtractFeature();
		HandelFeature handelFeature = new HandelFeature();
		WriteData writeData = new WriteData();
		SlideWindow slideWindow = new SlideWindow();
		HandleDistance handleDistance = new HandleDistance();

		List<DataItem> data = new ArrayList<DataItem>();
		BeginEndTime bet = new BeginEndTime();
		try {
			data = readData.readPAMAPDataFromFile(filePath, true, dimension);
			bet = readData.readPAMAPTimeFile(filePath, lable);
		} catch (IOException e) {
		}
		if (data.size() > 0 && bet.getBegin() * bet.getEnd() != 0) {

			Feature feature = extractFeature.getFeature(data, config.getThreshold_window(), config.getProbability(), //abnormal extraction
					config.getInterval());
			// writeData.writeData(path+subject+"_threshold",
			// feature.getThreshold(), 101);
			// writeData.writeData(path+subject+"_burst", feature.getBurst(),
			// 101);
			// writeData.writeData(path+subject+"_abnormal",
			// feature.getAbnormal(), 101);
			List<List<DataItem>> datas = slideWindow.extractWindow(feature.getAbnormal(), config.getWindow_length());//获取窗口

			List<DataItem> data_full = readData.readPAMAPDataFromFile(filePath, dimension);
			printPattern(data_full, datas, path, bet, config.getWindow_length());

			// long mark_time = 0;
			// List<List<Double>> maps = new ArrayList<>();
			// List<List<Double>> maps_posi = new ArrayList<>();
			// int n = 1;
			// for(int i = 0; i < datas.size(); i ++){
			// if(datas.get(i).get(0).getTimestamp() > mark_time){
			// mark_time = datas.get(i).get(0).getTimestamp();
			// List<Double> map = handelFeature.handleFeature(datas.get(i),
			// config.getN_segment());
			//
			// if(mark_time >= bet.getBegin()*10000 && mark_time <
			// bet.getEnd()*10000){
			//// writeData.writeData(path+subject+"/posi/"+mark_time,
			// datas.get(i), 0);
			//// writeData.writeData(path+subject+"/posi/map/"+mark_time, map,
			// 0);
			// maps_posi.add(map);
			// continue;
			//
			// }
			//
			//// writeData.writeData(path+subject+"/"+mark_time+"_"+n,
			// datas.get(i), 0);
			//// writeData.writeData(path+subject+"/map/"+mark_time+"_"+n, map,
			// 0);
			// maps.add(map);
			// n ++;
			//// logger.info(mark_time);
			//
			//
			// }
			// }

			//// List<List<DataItem>> map_distance =
			//// handleDistance.calDistance(maps_posi, maps, 0);
			// List<List<DataItem>> map_distance =
			//// handleDistance.calDistance(maps, maps_posi, 1);
			//
			// for(int i = 0; i < map_distance.size(); i ++){
			//// writeData.writeData(path+subject+"/posi/map/distance/"+i,
			//// map_distance.get(i), 0);
			// }
			//
			// List<CountNum> count =
			//// handleDistance.analyzeDistance(map_distance, config.getK());
			//// writeData.writeData(path+subject+"/posi/map/"+0, count, 0);
			//
			// map_distance = handleDistance.calDistance(maps_posi, maps, 0);
			// for(int i = 0; i < map_distance.size(); i ++){
			//// writeData.writeData(path+subject+"/posi/map/distance/"+i,
			//// map_distance.get(i), 0);
			// }
			// count = handleDistance.analyzeDistance(map_distance,
			//// config.getK());
		}
		logger.info("Fin.");
	}

	// given time point
	public void testOnPAMAP(String subject, PAMAPDimension dimension) {
		PAMAPClassifier pamapClassifier = new PAMAPClassifier();
//		pamapClassifier.OneSidePaaClassifier(subject);
		pamapClassifier.OneSideClassifier(subject);
//		pamapClassifier.TwoSidesClassifier(subject);
	}
	
	// within time range
	public void testOnPAMAP(String subject, Activities lable, PAMAPDimension dimension) {
		PAMAPClassifier pamapClassifier = new PAMAPClassifier();
		pamapClassifier.TimeRangeClassifier(subject, lable, dimension);
	}

	
	public static void printPattern(List<DataItem> data, List<List<DataItem>> windows, String path, BeginEndTime bet,
			long window_length) throws IOException {
		BinarySearch binarySearch = new BinarySearch();
		WriteData writeData = new WriteData();
		int count_posi = 0;
		int count_nega = 0;
		List<List<DataItem>> posi = new ArrayList<>();
		List<List<DataItem>> nega = new ArrayList<>();
		for (List<DataItem> window : windows) {

			long mid = 0;
			double max = 0;
			for (DataItem di : window) {
				if (di.getValue() > max) {
					mid = di.getTimestamp();
					max = di.getValue();
				}
			}

			long begin = mid - window_length / 2;
			int begin_index = binarySearch.binarySearch(data, begin, 1);
			long end = mid + window_length / 2;
			int end_index = binarySearch.binarySearch(data, end, 0);
			if (begin >= bet.getBegin() * 10000 && end <= bet.getEnd() * 10000) {
				logger.info("POSI-begin: "+begin);
				count_posi++;
				// writeData.writeData(path+subject+"/posipattern/"+count_posi+"_"+lable,
				// data.subList(begin_index, end_index+1));
				posi.add(data.subList(begin_index, end_index + 1));
			} else {
				logger.info("NEG-BEGIN: "+end);
				count_nega++;
				// writeData.writeData(path+subject+"/negapattern/"+count_nega+"_"+lable,
				// data.subList(begin_index, end_index+1));
				nega.add(data.subList(begin_index, end_index + 1));
			}

		}

		writeData.writeDataUCRFormat(path + subject + "\\dataset\\posi", posi, 1,",");
		writeData.writeDataUCRFormat(path + subject + "\\dataset\\nega", nega, 0,",");
	}

}
